/**
 * * 14/05/2010
 * @author Kal�u Caminha
 * @author William Rodrigues
 * @author Rodrigo Coelho
 */

package semantico;

/**
 *
 * @author CoelhoNB
 */
public class TabelaSimbolos {

    /*
     * ls -> ListaSimbolos
     */
    protected Identificador[] lsReferencia;
    protected String[] lsNome;
    protected int[] lsNivel;

    protected int numS;
    protected int maxArray;

    public TabelaSimbolos() {
        this.numS = 0;
        this.lsReferencia = new Identificador[100];
        this.lsNome = new String[100];
        this.lsNivel = new int[100];

    }

    public void insere(Identificador object){

        this.confereTamanhoArrays();
        this.lsReferencia[this.getNumS()] = object;
        this.lsNome[this.getNumS()] = object.getNome();
        this.lsNivel[this.getNumS()] = object.getNivel();
        this.numS++;
    }

    public int[] getLsNivel() {
        return lsNivel;
    }

    public void setLsNivel(int[] lsNivel) {
        this.lsNivel = lsNivel;
    }

    public String[] getLsNome() {
        return lsNome;
    }

    public void setLsNome(String[] lsNome) {
        this.lsNome = lsNome;
    }

    public Identificador[] getLsReferencia() {
        return lsReferencia;
    }

    public void setLsReferencia(Identificador[] lsReferencia) {
        this.lsReferencia = lsReferencia;
    }

    public int temSimboloNivelAcima(String id, int nivel){

        if(this.numS > 0){
            if(id.equals(this.getIdentificadorPrograma().getNome()) ){
                return 0;
            }
        }

        int x = this.getNumS();
        for(int i = x-1; i > 0; i--){
            if(this.lsNivel[i] <= nivel){
                if(this.lsNome[i].equals(id)){
                    return i;
                }
            }
        }
        return -1;
    }

    public int temSimbolo(String id, int nivel){

        if(this.numS > 0){
            if(id.equals(this.getIdentificadorPrograma().getNome()) ){
                return 0;
            }
        }

        int x = this.getNumS();
        for(int i = x; i > 0; i--){
            if(this.lsNivel[i] == nivel){
                if(this.lsNome[i].equals(id)){
                    return i;
                }
            }
        }
        return -1;
    }
   

    public Identificador getIdentificador(int index){
        return this.lsReferencia[index];
    }

    public Identificador getIdentificadorPrograma(){
        return this.lsReferencia[0];
    }

    /* Utilit�rios */

    public void confereTamanhoArrays(){
        if(this.getNumS() == this.getMaxArray()){
            Identificador[] lsReferenciaTemp = new Identificador[this.getMaxArray()];
            String[] lsNomeTemp = new String[this.getMaxArray()];
            int[] lsNivelTemp = new int[this.getMaxArray()];

            int x = this.getNumS();
            for(int i = 0; i < x; i++){
                lsReferenciaTemp[i] = lsReferencia[i];
                lsNomeTemp[i] = lsNome[i];
                lsNivelTemp[i] = lsNivel[i];
            }

            this.setMaxArray(this.getMaxArray()+100);

            this.lsReferencia = new Identificador[this.getMaxArray()];
            this.lsNome = new String[this.getMaxArray()];
            this.lsNivel = new int[this.getMaxArray()];

            for(int i = 0; i < x; i++){
                lsReferencia[i] = lsReferenciaTemp[i];
                lsNome[i] = lsNomeTemp[i];
                lsNivel[i] = lsNivelTemp[i];
            }
        }
    }

    /* get and set */

    public int getMaxArray() {
        return maxArray;
    }

    public void setMaxArray(int maxArray) {
        this.maxArray = maxArray;
    }

    public int getNumS() {
        return numS;
    }

    public void setNumS(int numS) {
        this.numS = numS;
    }

	public void removeSimbolosDoNivel(int nivel){
		int x = this.getNumS();
		int numRemovidos = 0;
        for(int i = 1; i < x; i++){
            if(this.lsNivel[i] == nivel){
                this.lsNivel[i] = -1;
                this.lsNome[i] = null;
                this.lsReferencia[i] = null;
				numRemovidos++;
            }
        }
		this.setNumS(x-numRemovidos);
	}

	public Procedimento getUltimoProcedimento(){
		int x = this.getNumS();		
        for(int i = x-1; i > 0; i--){
            if(this.lsReferencia[i] instanceof Procedimento || this.lsReferencia[i] instanceof Funcao){
				return (Procedimento)this.lsReferencia[i];
			}
        }
		return null;
	}

	@Override
    public String toString(){
        String s = "";
        for(int i = 0; i < this.getNumS(); i++){
            s+= this.lsReferencia[i]+"\n ";

        }        
        return s;
    }


}
